/**
 * 
 */
package pe.bf.extranet.dao.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialException;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Logger;

import pe.bf.base.dao.impl.BaseDAOImpl;
import pe.bf.base.types.OutParameter;
import pe.bf.domain.bean.Abono;
import pe.bf.domain.bean.Adjunto;
import pe.bf.domain.bean.Empleado;
import pe.bf.domain.bean.Empresa;
import pe.bf.domain.bean.Moneda;
import pe.bf.domain.bean.SolicitudAbono;
import pe.bf.domain.bean.TipoDocumento;
import pe.bf.domain.bean.Transferencia;
import pe.bf.domain.exceptions.DomainException;
import pe.bf.extranet.dao.SolicitudAbonoDAO;

/**
 * @author mchavez
 * 
 */
public class SolicitudAbonoDAOImpl extends BaseDAOImpl implements
		SolicitudAbonoDAO {

	Logger logger = Logger.getLogger(SolicitudAbonoDAOImpl.class);

	 static final String USP_CRE_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_CRE_SOLIC_ABONO(?,?,?,?,?,?,?,?,?,?,?,?)}";
	 static final String REG_TRANSFERENCIAS = "{call PGK_SOLICITUDABONO.REG_TRANSFERENCIAS(?,?)}";
	 static final String USP_CRE_ABONO = "{call PGK_SOLICITUDABONO.USP_CRE_ABONO(?,?,?,?,?,?,?)}";
	 static final String USP_ACT_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_ACT_SOLIC_ABONO(?,?,?)}";
	 static final String USP_ELI_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_ELI_SOLIC_ABONO(?)}";
	 static final String USP_LIS_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_LIS_SOLIC_ABONO(?)}";
	 static final String USP_LIS_SOLIC_ABONO_EMPRESA = "{call PGK_SOLICITUDABONO.USP_LIS_SOLIC_ABONO_EMPRESA(?,?)}";
	 static final String USP_LIS_DET_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_LIS_DET_SOLIC_ABONO(?,?,?)}";

	/**
	 * 
	 * @param dataSource
	 */
	public SolicitudAbonoDAOImpl(DataSource dataSource) {
		super(dataSource);
	}

	@Override
	public List<String> createSolicitudAbono(SolicitudAbono solicitudAbono)
			throws DomainException  {
		List<String> errores=new ArrayList();
		try {
			solicitudAbono.setIdSolicitudabono(invokeStoreProcedureGetAbono(USP_CRE_SOLIC_ABONO, 
					solicitudAbono.getNombrearchivo(), 
					solicitudAbono.getDescripcion(), 
					solicitudAbono.getMoneda(),
					solicitudAbono.getMontototal(),
					solicitudAbono.getNroempleados(),
					solicitudAbono.getTotalempleados(),
					solicitudAbono.getTipoabono(), 
					solicitudAbono.getUsuariocreacion(),
					solicitudAbono.getAdjunto().getArchivo(),
					solicitudAbono.getEmpresa().getIdEmpresa(),
					solicitudAbono.getFechacargaArchivo(),
					new OutParameter(OracleTypes.VARCHAR)));
				    registrarTransferencias(solicitudAbono.getTransferencias(), solicitudAbono.getIdSolicitudabono());
					errores=createDetalleSolicitudAbono((List)solicitudAbono.getAbonos(),solicitudAbono.getIdSolicitudabono());
		}catch (Exception e) {
			e.printStackTrace();
			logger.error(e, e.fillInStackTrace());
			errores.add("Error al grabar cabecera =" + e.getMessage());
			throw new DomainException(e);
		}
		finally{
			return errores;
		}
			
	
	}
	
	

	@Override
	public List<String> createDetalleSolicitudAbono(List<Abono> detalle,long id)
			throws DomainException {
		List<String> errores=new ArrayList();
		
		for(Abono abono:detalle){
			try {
				System.out.println("moneda " +abono.getMoneda());
				invokeStoreProcedure(USP_CRE_ABONO,  
						id,
					    abono.getMoneda(),
					    abono.getMonto(),
					    abono.getNombres(),
					    abono.getNrocuenta(),
					    abono.getNrodocumento(),
					    abono.getTipodocumento());
				
			} catch (Exception e) {
				errores.add("Abono "+abono.getNrocuenta()+" con error "+e.getMessage());
				e.printStackTrace();
			} 
		}
		return errores;
	}
	
	public List<String> registrarTransferencias(List<Transferencia> detalle,long id)
			throws DomainException {
		List<String> errores=new ArrayList();
		for(Transferencia tra:detalle){
			try {
				invokeStoreProcedure(REG_TRANSFERENCIAS,  
						id,
						tra.getIdTransferencia()
						);
				
			} catch (Exception e) {
				throw new DomainException(e);  
			} 
		}
		return errores;
	}
	
	
	@Override
	public void actualizarSolicitudAbono(SolicitudAbono solicitudAbono)
			throws DomainException {
		try {
			invokeStoreProcedure(USP_ACT_SOLIC_ABONO,
					solicitudAbono.getIdSolicitudabono(),
					solicitudAbono.getEstado(),
					solicitudAbono.getUsuarioprobacion() 
					);	
		} catch (Exception e) {
				e.printStackTrace();
		}
		
	}

	@Override
	public void eliminarSolicitudAbono(SolicitudAbono solicitudAbono)
			throws DomainException {
		invokeStoreProcedure(USP_ELI_SOLIC_ABONO,
				solicitudAbono.getIdSolicitudabono());
	}

	@Override
	public List<SolicitudAbono> listarSolicitudAbono()
			throws DomainException {

		ResultSet resultSet = invokeStoreProcedureRs(USP_LIS_SOLIC_ABONO,
				new OutParameter(OracleTypes.CURSOR));
		List<SolicitudAbono> solicitudAbonoList = new ArrayList<SolicitudAbono>();
		SolicitudAbono solicitudAbono=new SolicitudAbono();
		try {
			while (resultSet.next()) {
				solicitudAbono = new SolicitudAbono();
				solicitudAbono.setIdSolicitudabono(resultSet.getLong("ID_SOLICITUDABONO"));
				solicitudAbono.setEstado(resultSet.getString("ESTADO"));  
				solicitudAbono.setNombrearchivo(resultSet.getString("NOMBREARCHIVO"));
				solicitudAbono.setFechaaprobacion(resultSet.getDate("FECHAAPROBACION"));
				solicitudAbono.setFechaprocesobf(resultSet.getDate("FECHAPROCESOBF"));
				Empresa empresa =new Empresa();
				empresa.setNombres(resultSet.getString("EMPRESA"));
				empresa.setRuc(resultSet.getString("RUCEMPRESA"));
				solicitudAbono.setEmpresa(empresa);
				solicitudAbono.setDescripcion(resultSet.getString("DESCRIPCION"));
				solicitudAbono.setNroempleados(resultSet.getBigDecimal("NROEMPLEADOS"));
				solicitudAbono.setMontototal(resultSet.getBigDecimal("MONTOTOTAL"));
				solicitudAbono.setTotalempleados(resultSet.getBigDecimal("TOTALEMPLEADOS"));
				solicitudAbono.setTipoabono(resultSet.getString("TIPOABONO"));				
				solicitudAbono.setMoneda(resultSet.getString("MONEDA"));
				solicitudAbono.setUsuariocreacion(resultSet.getString("USUARIOPROBACION"));
				solicitudAbono.setUsuarioprobacion(resultSet.getString("USUARIOCREACION"));
				
				solicitudAbonoList.add(solicitudAbono);
			}
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}
		close(resultSet);
		return solicitudAbonoList;
	}

	@Override
	public List<SolicitudAbono> listarSolicitudAbonoPorEmpresa(
			BigInteger codigoEmpresa) throws DomainException {

		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_SOLIC_ABONO_EMPRESA, codigoEmpresa.longValue()+"", new OutParameter(OracleTypes.CURSOR));
		ResultSet resultSet=null;
		List<SolicitudAbono> solicitudAbonoList = new ArrayList<SolicitudAbono>();
		SolicitudAbono solicitudAbono=new SolicitudAbono(); 
		try {
			resultSet = (ResultSet) cal.getObject(2);
			while (resultSet.next()) {
				solicitudAbono = new SolicitudAbono();
				solicitudAbono.setIdSolicitudabono(resultSet.getLong("ID_SOLICITUDABONO"));
				solicitudAbono.setEstado(resultSet.getString("ESTADO"));  
				solicitudAbono.setNombrearchivo(resultSet.getString("NOMBREARCHIVO"));
				solicitudAbono.setFechacarga(resultSet.getDate("FECHACREACION"));
				solicitudAbono.setFechaaprobacion(resultSet.getDate("FECHAAPROBACION"));
				solicitudAbono.setFechaprocesobf(resultSet.getDate("FECHAPROCESOBF"));
				solicitudAbono.setDescripcion(resultSet.getString("DESCRIPCION"));
				solicitudAbono.setNroempleados(resultSet.getBigDecimal("NROEMPLEADOS"));
				solicitudAbono.setMontototal(resultSet.getBigDecimal("MONTOTOTAL"));
				solicitudAbono.setTotalempleados(resultSet.getBigDecimal("TOTALEMPLEADOS"));
				solicitudAbono.setTipoabono(resultSet.getString("TIPOABONO"));				
				solicitudAbono.setMoneda(resultSet.getString("MONEDA"));
				solicitudAbono.setUsuariocreacion(resultSet.getString("USUARIOPROBACION"));
				solicitudAbono.setUsuarioprobacion(resultSet.getString("USUARIOCREACION"));
				Empresa empresa =new Empresa();
				empresa.setNombres(resultSet.getString("EMPRESA"));
				empresa.setRuc(resultSet.getString("RUCEMPRESA"));
				solicitudAbono.setEmpresa(empresa);
				solicitudAbonoList.add(solicitudAbono);
			}
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		return solicitudAbonoList;
	}

	@Override
	public List<Abono> listarDetalleSolicitudAbono(
			BigInteger codigoEmpresa, BigInteger codigoSolicitudAbono)
			throws DomainException {
		ResultSet resultSet=null;
		CallableStatement cal =invokeStoreProcedureCallable(
				USP_LIS_DET_SOLIC_ABONO, codigoEmpresa.longValue()+"",
				codigoSolicitudAbono.longValue()+"", new OutParameter(OracleTypes.CURSOR));
		
		List<Abono> abonoList = new ArrayList<Abono>();
		Abono abono=new Abono(); 
		try {
			resultSet = (ResultSet) cal.getObject(3);
			while (resultSet.next()) { 
				abono=new Abono();   
				abono.setIdAbono(resultSet.getLong("ID_ABONO"));
				/*Falta hacer la busqueda de la solicitud por id*/  
				SolicitudAbono solicitudAbono=new SolicitudAbono();
				solicitudAbono.setIdSolicitudabono(resultSet.getLong("ID_SOLICITUDABONO"));

				abono.setSolicitudabono(solicitudAbono);
				abono.setTipodocumento(resultSet.getString("TIPODOCUMENTO"));
				abono.setNrodocumento(resultSet.getString("NRODOCUMENTO"));
				abono.setNombres(resultSet.getString("NOMBRES"));
				abono.setNrocuenta(resultSet.getString("NROCUENTA"));
				abono.setMoneda(resultSet.getString("MONEDA"));
				abono.setMonto(resultSet.getBigDecimal("MONTO"));
				abono.setImporteabono(resultSet.getBigDecimal("IMPORTEABONO"));
				abono.setReferenciaadcional(resultSet.getString("REFERENCIAADCIONAL"));
				abono.setNotaabono(resultSet.getBigDecimal("NOTAABONO")); 											
				abono.setEstado(resultSet.getString("ESTADO"));
				
				abonoList.add(abono);
			}
		} catch (SQLException e) {
			e.printStackTrace();
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return abonoList;	
		}
		
	}

 
	

}
